package entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import exception.AlmiranteException;

@Entity
@Table(name="requisito", schema="almirante", 
	uniqueConstraints=@UniqueConstraint(columnNames={"nome", "id_projeto"}))
public class Requisito {
	@Id
	@SequenceGenerator(name="requisito_seq", sequenceName="requisito_id_requisito_seq", schema="almirante")
	@GeneratedValue(strategy=GenerationType.AUTO, generator="requisito_seq")
	@Column(name="id_requisito")
	private Long id;
	
	@Enumerated(EnumType.ORDINAL)
	@Column(name="tipo", nullable=false)
	private TipoRequisito tipo;
	
	@Column(name="nome", length=40, nullable=false)
	private String nome;
	
	@Column(name="descricao", length=200)
	private String descricao;
	
	@Column(name="prioridade", nullable=false)
	private Integer prioridade;
	
	@Enumerated
	@Column(name="situacao", nullable=false)
	private SituacaoRequisito situacao;
	
	@Column(name="solicitante", length=80)
	private String solicitante;
	
	@Column(name="estabilidade")
	private Integer estabilidade;
	
	@Column(name="impacto_arquitetura")
	private Integer impactoArquitetura;
	
	@ManyToOne
	@JoinColumn(name="id_projeto", referencedColumnName="id_projeto", nullable=false)
	private Projeto projeto;
	
	public Requisito() {}
	
	public Requisito(String nome) {
		this.nome = nome;
	}
	
	public static enum TipoRequisito {
		FUNCIONAL("Funcional"), NAO_FUNCIONAL("Não-Funcional");
		
		private String descricao;
		TipoRequisito(String descricao) {
			this.descricao = descricao;
		}
		
		public String getDescricao() {
			return this.descricao;
		}
	}
	
	public static enum SituacaoRequisito {
		PROPOSTO("Proposto"), 
		REJEITADO("Rejeitado"), 
		APROVADO("Aprovado");
		
		private String descricao;
		
		SituacaoRequisito(String descricao) {
			this.descricao = descricao;
		}

		public String getDescricao() {
			return descricao;
		}		
	}

	public TipoRequisito getTipo() {
		return tipo;
	}

	public void setTipo(TipoRequisito tipo) {
		this.tipo = tipo;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	
	public Integer getPrioridade() {
		return prioridade;
	}

	public void setPrioridade(Integer prioridade) {
		this.prioridade = prioridade;
	}

	void setProjeto(Projeto projeto) {
		if (this.projeto != null)
			throw new AlmiranteException("Requisito já está vinculado a um projeto.");
		this.projeto = projeto;
	}

	public Projeto getProjeto() {
		return projeto;
	}
	
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
	
	public SituacaoRequisito getSituacao() {
		return situacao;
	}

	public void setSituacao(SituacaoRequisito situacao) {
		this.situacao = situacao;
	}
	
	public String getSolicitante() {
		return solicitante;
	}

	public void setSolicitante(String solicitante) {
		this.solicitante = solicitante;
	}

	public Integer getEstabilidade() {
		return estabilidade;
	}

	public void setEstabilidade(Integer estabilitade) {
		this.estabilidade = estabilitade;
	}

	public Integer getImpactoArquitetura() {
		return impactoArquitetura;
	}

	public void setImpactoArquitetura(Integer impactoArquitetura) {
		this.impactoArquitetura = impactoArquitetura;
	}

	// hashCode e equals
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((nome == null) ? 0 : nome.hashCode());
		result = prime * result + ((projeto == null) ? 0 : projeto.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Requisito other = (Requisito) obj;
		if (nome == null) {
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		if (projeto == null) {
			if (other.projeto != null)
				return false;
		} else if (!projeto.equals(other.projeto))
			return false;
		return true;
	}

}
